package core.domain;

import java.io.Serializable;
import java.util.List;

import javax.xml.bind.annotation.XmlRootElement;
@XmlRootElement
public class Torrent implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1745124889734895900L;
	
	private String fileName = null;
	private int fileHash = -1;
	private int numberOfPieces = -1;
	
	public Torrent() {
	}
	
	public Torrent(String fileName, List<Part> parts) {
		this.fileName = fileName;
		this.fileHash = calculateTorrentHash(parts);
		this.numberOfPieces = parts.size();
		setParent(parts);
	}
	
	/**
	 * call it only when torrent is fully up (got name, hash, and number if pieces!)
	 * @param parts
	 */
	private void setParent(List<Part> parts) {
		//TODO: create Assert class with static methods!
		assert fileName != null;
		assert fileHash != -1;
		assert numberOfPieces != -1;
		for(Part part:parts){
			part.setParentTorrent(this);
		}
		
	}

	public static int calculateTorrentHash(List<Part> parts){
		int result = 0;
		for(Part part : parts){
			result += Part.calulatePartHash(part.getPayloadRows());
		}
		return result;
	}
	
	public String getFileName() {
		return fileName;
	}
	public void setFileName(String fileName) {
		this.fileName = fileName;
	}
	public int getFileHash() {
		return fileHash;
	}
	public void setFileHash(int fileHash) {
		this.fileHash = fileHash;
	}
	public int getNumberOfPieces() {
		return numberOfPieces;
	}
	public void setNumberOfPieces(int numberOfPieces) {
		this.numberOfPieces = numberOfPieces;
	}
	
	

	@Override
	public int hashCode() {
		//either this or the hash field can be returned here
		final int prime = 31;
		int result = 1;
		result = prime * result + fileHash;
		result = prime * result + ((fileName == null) ? 0 : fileName.hashCode());
		result = prime * result + numberOfPieces;
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Torrent other = (Torrent) obj;
		if (fileHash != other.fileHash)
			return false;
		if (fileName == null) {
			if (other.fileName != null)
				return false;
		} else if (!fileName.equals(other.fileName))
			return false;
		if (numberOfPieces != other.numberOfPieces)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Torrent [fileName=" + fileName + ", fileHash=" + fileHash
				+ ", numberOfPieces=" + numberOfPieces + "]";
	}
	
	
	
}
